﻿
using System;
using System.Collections.Generic;
using System.IO;

public class MSGEncodeManager
{
    /// <summary>
    /// 封装数据包
    /// </summary>
    /// <param name="buff"></param>
    /// <returns></returns> 
    public static byte[] MsgPackEncode(byte[] buff)
    {
        MemoryStream ms = new MemoryStream();//创建内存流对象
        BinaryWriter sw = new BinaryWriter(ms);//写入二进制对象流
                                               //写入消息长度
        sw.Write(buff.Length);
        //写入消息体
        sw.Write(buff);
        byte[] result = new byte[ms.Length];
        Buffer.BlockCopy(ms.GetBuffer(), 0, result, 0, (int)ms.Length);
        sw.Close();
        ms.Close();
        return result;
    }
    /// <summary>
    /// 拆分数据包
    /// </summary>
    /// <param name="cache"></param>
    /// <returns></returns> 
    public static byte[] MsgPackDecode(ref List<byte> cache)
    {
        if (cache.Count < 4) return null;//int32占4个字节
        MemoryStream ms = new MemoryStream(cache.ToArray());//创建内存流对象，并将缓存数据写入进去
        BinaryReader br = new BinaryReader(ms);//读取二进制流
        int length = br.ReadInt32();//从缓存中读取int类型消息长度
        if (length > ms.Length - ms.Position)//消息尚未读取完，等待消息下次到达后处理
        {
            return null;
        }
        //读取正确长度的数据
        byte[] result = br.ReadBytes(length);
        cache.Clear();//清空缓存
                      //将读取后的剩余数据写入缓存
        cache.AddRange(br.ReadBytes((int)(ms.Length - ms.Position)));
        br.Close();
        ms.Close();
        return result;
    }

    /// <summary>消息体序列化 </summary>
    public static byte[] MSGEncode(SocketModel model)
    { 
        
        ByteArray ba = new ByteArray();
        //写入顺序和读取顺序必须保持一致，不一致的话就会读取出错
        ba.WriteByte(model.Type);
        ba.WriteInt(model.Area);
        ba.WriteInt(model.Command);
        if (model.Message != null)//判断消息体是否为null
        {
            ba.WriteByteArray(SerializeUtil.ObjectToByteArray(model.Message));
        }
        byte[] result = ba.GetBuff();
        ba.Close();
        return result;
    }

    /// <summary> 消息体反序列化 </summary>
    public static SocketModel MSGDecode(byte[] value)
    { 
        ByteArray ba = new ByteArray(value);
        SocketModel model = new SocketModel();
        //写入顺序和读取顺序必须保持一致，不一致的话就会读取出错
        byte type = ba.ReadByte();
        int area = ba.ReadInt();
        int command = ba.ReadInt();
        //读取类型、区域码、和命令
        model.Type = type;
        model.Area = area;
        model.Command = command;
        if (ba.Readnable)//如果当前内存流中还有数据，说明是有消息体，则读取消息体
        {
            byte[] message = ba.ReadByteArray(ba.Length - ba.Position);
            model.Message = SerializeUtil.ByteArrayToObject(message);
        }
        ba.Close();
        return model;
    }


}

